{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "intro_to_sparse_data_and_embeddings.ipynb",
      "version": "0.3.2",
      "views": {},
      "default_view": {},
      "provenance": [],
      "collapsed_sections": [
        "mNCLhxsXyOIS",
        "eQS5KQzBybTY",
        "copyright-notice"
      ]
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "source": [
        "#### Copyright 2017 Google LLC."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "copyright-notice"
      }
    },
    {
      "source": [
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "execution_count": 0,
      "cell_type": "code",
      "outputs": [],
      "metadata": {
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        },
        "cellView": "both",
        "colab_type": "code",
        "id": "copyright-notice2"
      }
    },
    {
      "metadata": {
        "id": "PTaAdgy3LS8W",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " # \u7a00\u758f\u6570\u636e\u548c\u5d4c\u5165\u7b80\u4ecb\n",
        "\n",
        "**\u5b66\u4e60\u76ee\u6807\uff1a**\n",
        "* \u5c06\u5f71\u8bc4\u5b57\u7b26\u4e32\u6570\u636e\u8f6c\u6362\u4e3a\u7a00\u758f\u7279\u5f81\u77e2\u91cf\n",
        "* \u4f7f\u7528\u7a00\u758f\u7279\u5f81\u77e2\u91cf\u5b9e\u73b0\u60c5\u611f\u5206\u6790\u7ebf\u6027\u6a21\u578b\n",
        "* \u901a\u8fc7\u5c06\u6570\u636e\u6295\u5c04\u5230\u4e8c\u7ef4\u7a7a\u95f4\u7684\u5d4c\u5165\u6765\u5b9e\u73b0\u60c5\u611f\u5206\u6790 DNN \u6a21\u578b\n",
        "* \u5c06\u5d4c\u5165\u53ef\u89c6\u5316\uff0c\u4ee5\u4fbf\u67e5\u770b\u6a21\u578b\u5b66\u5230\u7684\u8bcd\u8bed\u4e4b\u95f4\u7684\u5173\u7cfb\n",
        "\n",
        "\u5728\u6b64\u7ec3\u4e60\u4e2d\uff0c\u6211\u4eec\u5c06\u63a2\u8ba8\u7a00\u758f\u6570\u636e\uff0c\u5e76\u4f7f\u7528\u5f71\u8bc4\u6587\u672c\u6570\u636e\uff08\u6765\u81ea [ACL 2011 IMDB \u6570\u636e\u96c6](http://ai.stanford.edu/~amaas/data/sentiment/)\uff09\u8fdb\u884c\u5d4c\u5165\u3002\u8fd9\u4e9b\u6570\u636e\u5df2\u88ab\u5904\u7406\u6210 `tf.Example` \u683c\u5f0f\u3002"
      ]
    },
    {
      "metadata": {
        "id": "2AKGtmwNosU8",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u8bbe\u7f6e\n",
        "\n",
        "\u6211\u4eec\u5bfc\u5165\u4f9d\u8d56\u9879\u5e76\u4e0b\u8f7d\u8bad\u7ec3\u6570\u636e\u548c\u6d4b\u8bd5\u6570\u636e\u3002[`tf.keras`](https://www.tensorflow.org/api_docs/python/tf/keras) \u4e2d\u5305\u542b\u4e00\u4e2a\u6587\u4ef6\u4e0b\u8f7d\u548c\u7f13\u5b58\u5de5\u5177\uff0c\u6211\u4eec\u53ef\u4ee5\u7528\u5b83\u6765\u68c0\u7d22\u6570\u636e\u96c6\u3002"
      ]
    },
    {
      "metadata": {
        "id": "jGWqDqFFL_NZ",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "from __future__ import print_function\n",
        "\n",
        "import collections\n",
        "import io\n",
        "import math\n",
        "\n",
        "import matplotlib.pyplot as plt\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "import tensorflow as tf\n",
        "from IPython import display\n",
        "from sklearn import metrics\n",
        "\n",
        "tf.logging.set_verbosity(tf.logging.ERROR)\n",
        "train_url = 'https://download.mlcc.google.cn/mledu-datasets/sparse-data-embedding/train.tfrecord'\n",
        "train_path = tf.keras.utils.get_file(train_url.split('/')[-1], train_url)\n",
        "test_url = 'https://download.mlcc.google.cn/mledu-datasets/sparse-data-embedding/test.tfrecord'\n",
        "test_path = tf.keras.utils.get_file(test_url.split('/')[-1], test_url)"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "6W7aZ9qspZVj",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u6784\u5efa\u60c5\u611f\u5206\u6790\u6a21\u578b"
      ]
    },
    {
      "metadata": {
        "id": "jieA0k_NLS8a",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u6211\u4eec\u6839\u636e\u8fd9\u4e9b\u6570\u636e\u8bad\u7ec3\u4e00\u4e2a\u60c5\u611f\u5206\u6790\u6a21\u578b\uff0c\u4ee5\u9884\u6d4b\u67d0\u6761\u8bc4\u4ef7\u603b\u4f53\u4e0a\u662f*\u597d\u8bc4*\uff08\u6807\u7b7e\u4e3a 1\uff09\u8fd8\u662f*\u5dee\u8bc4*\uff08\u6807\u7b7e\u4e3a 0\uff09\u3002\n",
        "\n",
        "\u4e3a\u6b64\uff0c\u6211\u4eec\u4f1a\u4f7f\u7528*\u8bcd\u6c47\u8868*\uff08\u5373\u6211\u4eec\u9884\u8ba1\u5c06\u5728\u6570\u636e\u4e2d\u770b\u5230\u7684\u6bcf\u4e2a\u672f\u8bed\u7684\u5217\u8868\uff09\uff0c\u5c06\u5b57\u7b26\u4e32\u503c `terms` \u8f6c\u6362\u4e3a\u7279\u5f81\u77e2\u91cf\u3002\u5728\u672c\u7ec3\u4e60\u4e2d\uff0c\u6211\u4eec\u521b\u5efa\u4e86\u4fa7\u91cd\u4e8e\u4e00\u7ec4\u6709\u9650\u672f\u8bed\u7684\u5c0f\u578b\u8bcd\u6c47\u8868\u3002\u5176\u4e2d\u7684\u5927\u591a\u6570\u672f\u8bed\u660e\u786e\u8868\u793a\u662f*\u597d\u8bc4*\u6216*\u5dee\u8bc4*\uff0c\u4f46\u6709\u4e9b\u53ea\u662f\u56e0\u4e3a\u6709\u8da3\u800c\u88ab\u6dfb\u52a0\u8fdb\u6765\u3002\n",
        "\n",
        "\u8bcd\u6c47\u8868\u4e2d\u7684\u6bcf\u4e2a\u672f\u8bed\u90fd\u4e0e\u7279\u5f81\u77e2\u91cf\u4e2d\u7684\u4e00\u4e2a\u5750\u6807\u76f8\u5bf9\u5e94\u3002\u4e3a\u4e86\u5c06\u6837\u672c\u7684\u5b57\u7b26\u4e32\u503c `terms` \u8f6c\u6362\u4e3a\u8fd9\u79cd\u77e2\u91cf\u683c\u5f0f\uff0c\u6211\u4eec\u6309\u4ee5\u4e0b\u65b9\u5f0f\u5904\u7406\u5b57\u7b26\u4e32\u503c\uff1a\u5982\u679c\u8be5\u672f\u8bed\u6ca1\u6709\u51fa\u73b0\u5728\u6837\u672c\u5b57\u7b26\u4e32\u4e2d\uff0c\u5219\u5750\u6807\u503c\u5c06\u4e3a 0\uff1b\u5982\u679c\u51fa\u73b0\u5728\u6837\u672c\u5b57\u7b26\u4e32\u4e2d\uff0c\u5219\u503c\u4e3a 1\u3002\u672a\u51fa\u73b0\u5728\u8be5\u8bcd\u6c47\u8868\u4e2d\u7684\u6837\u672c\u4e2d\u7684\u672f\u8bed\u5c06\u88ab\u5f03\u7528\u3002"
      ]
    },
    {
      "metadata": {
        "id": "2HSfklfnLS8b",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " **\u6ce8\u610f**\uff1a*\u6211\u4eec\u5f53\u7136\u53ef\u4ee5\u4f7f\u7528\u66f4\u5927\u7684\u8bcd\u6c47\u8868\uff0c\u800c\u4e14\u6709\u521b\u5efa\u6b64\u7c7b\u8bcd\u6c47\u8868\u7684\u4e13\u7528\u5de5\u5177\u3002\u6b64\u5916\uff0c\u6211\u4eec\u53ef\u4ee5\u6dfb\u52a0\u5c11\u91cf\u7684 OOV\uff08\u672a\u6536\u5f55\u8bcd\u6c47\uff09\u5206\u6876\uff0c\u60a8\u53ef\u4ee5\u5728\u5176\u4e2d\u5bf9\u8bcd\u6c47\u8868\u4e2d\u672a\u5305\u542b\u7684\u672f\u8bed\u8fdb\u884c\u54c8\u5e0c\u5904\u7406\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f\u5f03\u7528\u8fd9\u4e9b\u672f\u8bed\u3002\u6211\u4eec\u8fd8\u53ef\u4ee5\u4f7f\u7528__\u7279\u5f81\u54c8\u5e0c__\u6cd5\u5bf9\u6bcf\u4e2a\u672f\u8bed\u8fdb\u884c\u54c8\u5e0c\u5904\u7406\uff0c\u800c\u4e0d\u662f\u521b\u5efa\u663e\u5f0f\u8bcd\u6c47\u8868\u3002\u8fd9\u5728\u5b9e\u8df5\u4e2d\u5f88\u6709\u6548\uff0c\u4f46\u5374\u4e0d\u5177\u5907\u53ef\u89e3\u8bfb\u6027\uff08\u8fd9\u5bf9\u672c\u7ec3\u4e60\u975e\u5e38\u5b9e\u7528\uff09\u3002\u5982\u9700\u4e86\u89e3\u5904\u7406\u6b64\u7c7b\u8bcd\u6c47\u8868\u7684\u5de5\u5177\uff0c\u8bf7\u53c2\u9605 tf.feature_column \u6a21\u5757\u3002*"
      ]
    },
    {
      "metadata": {
        "id": "Uvoa2HyDtgqe",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u6784\u5efa\u8f93\u5165\u7ba1\u9053"
      ]
    },
    {
      "metadata": {
        "id": "O20vMEOurDol",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u9996\u5148\uff0c\u6211\u4eec\u6765\u914d\u7f6e\u8f93\u5165\u7ba1\u9053\uff0c\u4ee5\u5c06\u6570\u636e\u5bfc\u5165 TensorFlow \u6a21\u578b\u4e2d\u3002\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u51fd\u6570\u6765\u89e3\u6790\u8bad\u7ec3\u6570\u636e\u548c\u6d4b\u8bd5\u6570\u636e\uff08\u683c\u5f0f\u4e3a [TFRecord](https://www.tensorflow.org/guide/datasets#consuming_tfrecord_data)\uff09\uff0c\u7136\u540e\u8fd4\u56de\u4e00\u4e2a\u7531\u7279\u5f81\u548c\u76f8\u5e94\u6807\u7b7e\u7ec4\u6210\u7684\u5b57\u5178\u3002"
      ]
    },
    {
      "metadata": {
        "id": "SxxNIEniPq2z",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "def _parse_function(record):\n",
        "  \"\"\"Extracts features and labels.\n",
        "  \n",
        "  Args:\n",
        "    record: File path to a TFRecord file    \n",
        "  Returns:\n",
        "    A `tuple` `(labels, features)`:\n",
        "      features: A dict of tensors representing the features\n",
        "      labels: A tensor with the corresponding labels.\n",
        "  \"\"\"\n",
        "  features = {\n",
        "    \"terms\": tf.VarLenFeature(dtype=tf.string), # terms are strings of varying lengths\n",
        "    \"labels\": tf.FixedLenFeature(shape=[1], dtype=tf.float32) # labels are 0 or 1\n",
        "  }\n",
        "  \n",
        "  parsed_features = tf.parse_single_example(record, features)\n",
        "  \n",
        "  terms = parsed_features['terms'].values\n",
        "  labels = parsed_features['labels']\n",
        "\n",
        "  return  {'terms':terms}, labels"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "SXhTeeYMrp-l",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u4e3a\u4e86\u786e\u8ba4\u51fd\u6570\u662f\u5426\u80fd\u6b63\u5e38\u8fd0\u884c\uff0c\u6211\u4eec\u4e3a\u8bad\u7ec3\u6570\u636e\u6784\u5efa\u4e00\u4e2a `TFRecordDataset`\uff0c\u5e76\u4f7f\u7528\u4e0a\u8ff0\u51fd\u6570\u5c06\u6570\u636e\u6620\u5c04\u5230\u7279\u5f81\u548c\u6807\u7b7e\u3002"
      ]
    },
    {
      "metadata": {
        "id": "oF4YWXR0Omt0",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "# Create the Dataset object.\n",
        "ds = tf.data.TFRecordDataset(train_path)\n",
        "# Map features and labels with the parse function.\n",
        "ds = ds.map(_parse_function)\n",
        "\n",
        "ds"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "bUoMvK-9tVXP",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u8fd0\u884c\u4ee5\u4e0b\u5355\u5143\uff0c\u4ee5\u4ece\u8bad\u7ec3\u6570\u636e\u96c6\u4e2d\u83b7\u53d6\u7b2c\u4e00\u4e2a\u6837\u672c\u3002"
      ]
    },
    {
      "metadata": {
        "id": "Z6QE2DWRUc4E",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "n = ds.make_one_shot_iterator().get_next()\n",
        "sess = tf.Session()\n",
        "sess.run(n)"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "jBU39UeFty9S",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u73b0\u5728\uff0c\u6211\u4eec\u6784\u5efa\u4e00\u4e2a\u6b63\u5f0f\u7684\u8f93\u5165\u51fd\u6570\uff0c\u53ef\u4ee5\u5c06\u5176\u4f20\u9012\u7ed9 TensorFlow Estimator \u5bf9\u8c61\u7684 `train()` \u65b9\u6cd5\u3002"
      ]
    },
    {
      "metadata": {
        "id": "5_C5-ueNYIn_",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "# Create an input_fn that parses the tf.Examples from the given files,\n",
        "# and split them into features and targets.\n",
        "def _input_fn(input_filenames, num_epochs=None, shuffle=True):\n",
        "  \n",
        "  # Same code as above; create a dataset and map features and labels.\n",
        "  ds = tf.data.TFRecordDataset(input_filenames)\n",
        "  ds = ds.map(_parse_function)\n",
        "\n",
        "  if shuffle:\n",
        "    ds = ds.shuffle(10000)\n",
        "\n",
        "  # Our feature data is variable-length, so we pad and batch\n",
        "  # each field of the dataset structure to whatever size is necessary.     \n",
        "  ds = ds.padded_batch(25, ds.output_shapes)\n",
        "  \n",
        "  ds = ds.repeat(num_epochs)\n",
        "\n",
        "  \n",
        "  # Return the next batch of data.\n",
        "  features, labels = ds.make_one_shot_iterator().get_next()\n",
        "  return features, labels"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "Y170tVlrLS8c",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u4efb\u52a1 1\uff1a\u4f7f\u7528\u5177\u6709\u7a00\u758f\u8f93\u5165\u548c\u663e\u5f0f\u8bcd\u6c47\u8868\u7684\u7ebf\u6027\u6a21\u578b\n",
        "\n",
        "\u5bf9\u4e8e\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u6a21\u578b\uff0c\u6211\u4eec\u5c06\u4f7f\u7528 50 \u4e2a\u4fe1\u606f\u6027\u672f\u8bed\u6765\u6784\u5efa [`LinearClassifier`](https://www.tensorflow.org/api_docs/python/tf/estimator/LinearClassifier) \u6a21\u578b\uff1b\u59cb\u7ec8\u4ece\u7b80\u5355\u5165\u624b\uff01\n",
        "\n",
        "\u4ee5\u4e0b\u4ee3\u7801\u5c06\u4e3a\u6211\u4eec\u7684\u672f\u8bed\u6784\u5efa\u7279\u5f81\u5217\u3002[`categorical_column_with_vocabulary_list`](https://www.tensorflow.org/api_docs/python/tf/feature_column/categorical_column_with_vocabulary_list) \u51fd\u6570\u53ef\u4f7f\u7528\u201c\u5b57\u7b26\u4e32-\u7279\u5f81\u77e2\u91cf\u201d\u6620\u5c04\u6765\u521b\u5efa\u7279\u5f81\u5217\u3002"
      ]
    },
    {
      "metadata": {
        "id": "B5gdxuWsvPcx",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "# 50 informative terms that compose our model vocabulary. \n",
        "informative_terms = (\"bad\", \"great\", \"best\", \"worst\", \"fun\", \"beautiful\",\n",
        "                     \"excellent\", \"poor\", \"boring\", \"awful\", \"terrible\",\n",
        "                     \"definitely\", \"perfect\", \"liked\", \"worse\", \"waste\",\n",
        "                     \"entertaining\", \"loved\", \"unfortunately\", \"amazing\",\n",
        "                     \"enjoyed\", \"favorite\", \"horrible\", \"brilliant\", \"highly\",\n",
        "                     \"simple\", \"annoying\", \"today\", \"hilarious\", \"enjoyable\",\n",
        "                     \"dull\", \"fantastic\", \"poorly\", \"fails\", \"disappointing\",\n",
        "                     \"disappointment\", \"not\", \"him\", \"her\", \"good\", \"time\",\n",
        "                     \"?\", \".\", \"!\", \"movie\", \"film\", \"action\", \"comedy\",\n",
        "                     \"drama\", \"family\")\n",
        "\n",
        "terms_feature_column = tf.feature_column.categorical_column_with_vocabulary_list(key=\"terms\", vocabulary_list=informative_terms)"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "eTiDwyorwd3P",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u6784\u5efa `LinearClassifier`\uff0c\u5728\u8bad\u7ec3\u96c6\u4e2d\u8bad\u7ec3\u8be5\u6a21\u578b\uff0c\u5e76\u5728\u8bc4\u4f30\u96c6\u4e2d\u5bf9\u5176\u8fdb\u884c\u8bc4\u4f30\u3002\u9605\u8bfb\u4e0a\u8ff0\u4ee3\u7801\u540e\uff0c\u8fd0\u884c\u8be5\u6a21\u578b\u4ee5\u4e86\u89e3\u5176\u6548\u679c\u3002"
      ]
    },
    {
      "metadata": {
        "id": "HYKKpGLqLS8d",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "my_optimizer = tf.train.AdagradOptimizer(learning_rate=0.1)\n",
        "my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
        "\n",
        "feature_columns = [ terms_feature_column ]\n",
        "\n",
        "\n",
        "classifier = tf.estimator.LinearClassifier(\n",
        "  feature_columns=feature_columns,\n",
        "  optimizer=my_optimizer,\n",
        ")\n",
        "\n",
        "classifier.train(\n",
        "  input_fn=lambda: _input_fn([train_path]),\n",
        "  steps=1000)\n",
        "\n",
        "evaluation_metrics = classifier.evaluate(\n",
        "  input_fn=lambda: _input_fn([train_path]),\n",
        "  steps=1000)\n",
        "print(\"Training set metrics:\")\n",
        "for m in evaluation_metrics:\n",
        "  print(m, evaluation_metrics[m])\n",
        "print(\"---\")\n",
        "\n",
        "evaluation_metrics = classifier.evaluate(\n",
        "  input_fn=lambda: _input_fn([test_path]),\n",
        "  steps=1000)\n",
        "\n",
        "print(\"Test set metrics:\")\n",
        "for m in evaluation_metrics:\n",
        "  print(m, evaluation_metrics[m])\n",
        "print(\"---\")"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "J0ubn9gULS8g",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u4efb\u52a1 2\uff1a\u4f7f\u7528\u6df1\u5ea6\u795e\u7ecf\u7f51\u7edc (DNN) \u6a21\u578b\n",
        "\n",
        "\u4e0a\u8ff0\u6a21\u578b\u662f\u4e00\u4e2a\u7ebf\u6027\u6a21\u578b\uff0c\u6548\u679c\u975e\u5e38\u597d\u3002\u4f46\u662f\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 DNN \u6a21\u578b\u5b9e\u73b0\u66f4\u597d\u7684\u6548\u679c\u5417\uff1f\n",
        "\n",
        "\u6211\u4eec\u5c06 `LinearClassifier` \u5207\u6362\u4e3a [`DNNClassifier`](https://www.tensorflow.org/api_docs/python/tf/estimator/DNNClassifier)\u3002\u8fd0\u884c\u4ee5\u4e0b\u5355\u5143\uff0c\u770b\u770b\u60a8\u7684\u6a21\u578b\u6548\u679c\u5982\u4f55\u3002"
      ]
    },
    {
      "metadata": {
        "id": "jcgOPfEALS8h",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "##################### Here's what we changed ##################################\n",
        "classifier = tf.estimator.DNNClassifier(                                      #\n",
        "  feature_columns=[tf.feature_column.indicator_column(terms_feature_column)], #\n",
        "  hidden_units=[20,20],                                                       #\n",
        "  optimizer=my_optimizer,                                                     #\n",
        ")                                                                             #\n",
        "###############################################################################\n",
        "\n",
        "try:\n",
        "  classifier.train(\n",
        "    input_fn=lambda: _input_fn([train_path]),\n",
        "    steps=1000)\n",
        "\n",
        "  evaluation_metrics = classifier.evaluate(\n",
        "    input_fn=lambda: _input_fn([train_path]),\n",
        "    steps=1)\n",
        "  print(\"Training set metrics:\")\n",
        "  for m in evaluation_metrics:\n",
        "    print(m, evaluation_metrics[m])\n",
        "  print(\"---\")\n",
        "\n",
        "  evaluation_metrics = classifier.evaluate(\n",
        "    input_fn=lambda: _input_fn([test_path]),\n",
        "    steps=1)\n",
        "\n",
        "  print(\"Test set metrics:\")\n",
        "  for m in evaluation_metrics:\n",
        "    print(m, evaluation_metrics[m])\n",
        "  print(\"---\")\n",
        "except ValueError as err:\n",
        "  print(err)"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "cZz68luxLS8j",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u4efb\u52a1 3\uff1a\u5728 DNN \u6a21\u578b\u4e2d\u4f7f\u7528\u5d4c\u5165\n",
        "\n",
        "\u5728\u6b64\u4efb\u52a1\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528\u5d4c\u5165\u5217\u6765\u5b9e\u73b0 DNN \u6a21\u578b\u3002\u5d4c\u5165\u5217\u4f1a\u5c06\u7a00\u758f\u6570\u636e\u4f5c\u4e3a\u8f93\u5165\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a\u4f4e\u7ef4\u5ea6\u5bc6\u96c6\u77e2\u91cf\u4f5c\u4e3a\u8f93\u51fa\u3002"
      ]
    },
    {
      "metadata": {
        "id": "AliRzhvJLS8k",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " **\u6ce8\u610f**\uff1a*\u4ece\u8ba1\u7b97\u65b9\u9762\u800c\u8a00\uff0cembedding_column \u901a\u5e38\u662f\u7528\u4e8e\u5728\u7a00\u758f\u6570\u636e\u4e2d\u8bad\u7ec3\u6a21\u578b\u6700\u6709\u6548\u7684\u9009\u9879\u3002\u5728\u6b64\u7ec3\u4e60\u672b\u5c3e\u7684[\u53ef\u9009\u90e8\u5206](#scrollTo=XDMlGgRfKSVz)\uff0c\u6211\u4eec\u5c06\u66f4\u6df1\u5165\u5730\u8ba8\u8bba\u4f7f\u7528 `embedding_column` \u4e0e `indicator_column` \u4e4b\u95f4\u7684\u5b9e\u73b0\u5dee\u5f02\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u8fd9\u4e24\u8005\u4e4b\u95f4\u505a\u51fa\u6743\u8861\u3002*"
      ]
    },
    {
      "metadata": {
        "id": "F-as3PtALS8l",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u6267\u884c\u4ee5\u4e0b\u64cd\u4f5c\uff1a\n",
        "\n",
        "* \u901a\u8fc7\u5c06\u6570\u636e\u6295\u5c04\u5230\u4e8c\u7ef4\u7a7a\u95f4\u7684 `embedding_column` \u6765\u4e3a\u6a21\u578b\u5b9a\u4e49\u7279\u5f81\u5217\uff08\u5982\u9700\u8be6\u7ec6\u4e86\u89e3 `embedding_column` \u7684\u51fd\u6570\u7b7e\u540d\uff0c\u8bf7\u53c2\u9605\u76f8\u5173 [TF \u6587\u6863](https://www.tensorflow.org/api_docs/python/tf/feature_column/embedding_column)\uff09\u3002\n",
        "* \u5b9a\u4e49\u7b26\u5408\u4ee5\u4e0b\u89c4\u8303\u7684 `DNNClassifier`\uff1a\n",
        "  * \u5177\u6709\u4e24\u4e2a\u9690\u85cf\u5c42\uff0c\u6bcf\u4e2a\u5305\u542b 20 \u4e2a\u5355\u5143\n",
        "  * \u91c7\u7528\u5b66\u4e60\u901f\u7387\u4e3a 0.1 \u7684 AdaGrad \u4f18\u5316\u65b9\u6cd5\n",
        "  * `gradient_clip_norm \u503c\u4e3a 5.0`"
      ]
    },
    {
      "metadata": {
        "id": "UlPZ-Q9bLS8m",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " **\u6ce8\u610f**\uff1a*\u5728\u5b9e\u8df5\u4e2d\uff0c\u6211\u4eec\u53ef\u80fd\u4f1a\u5c06\u6570\u636e\u6295\u5c04\u5230 2 \u7ef4\u4ee5\u4e0a\uff08\u6bd4\u5982 50 \u6216 100\uff09\u7684\u7a7a\u95f4\u4e2d\u3002\u4f46\u5c31\u76ee\u524d\u800c\u8a00\uff0c2 \u7ef4\u662f\u6bd4\u8f83\u5bb9\u6613\u53ef\u89c6\u5316\u7684\u7ef4\u6570\u3002*"
      ]
    },
    {
      "metadata": {
        "id": "mNCLhxsXyOIS",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ### \u63d0\u793a"
      ]
    },
    {
      "metadata": {
        "id": "L67xYD7hLS8m",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "# Here's a example code snippet you might use to define the feature columns:\n",
        "\n",
        "terms_embedding_column = tf.feature_column.embedding_column(terms_feature_column, dimension=2)\n",
        "feature_columns = [ terms_embedding_column ]"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "iv1UBsJxyV37",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ### \u5b8c\u6210\u4ee5\u4e0b\u4ee3\u7801"
      ]
    },
    {
      "metadata": {
        "id": "5PG_yhNGLS8u",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "########################## YOUR CODE HERE ######################################\n",
        "terms_embedding_column = # Define the embedding column\n",
        "feature_columns = # Define the feature columns\n",
        "\n",
        "classifier = # Define the DNNClassifier\n",
        "################################################################################\n",
        "\n",
        "classifier.train(\n",
        "  input_fn=lambda: _input_fn([train_path]),\n",
        "  steps=1000)\n",
        "\n",
        "evaluation_metrics = classifier.evaluate(\n",
        "  input_fn=lambda: _input_fn([train_path]),\n",
        "  steps=1000)\n",
        "print(\"Training set metrics:\")\n",
        "for m in evaluation_metrics:\n",
        "  print(m, evaluation_metrics[m])\n",
        "print(\"---\")\n",
        "\n",
        "evaluation_metrics = classifier.evaluate(\n",
        "  input_fn=lambda: _input_fn([test_path]),\n",
        "  steps=1000)\n",
        "\n",
        "print(\"Test set metrics:\")\n",
        "for m in evaluation_metrics:\n",
        "  print(m, evaluation_metrics[m])\n",
        "print(\"---\")"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "eQS5KQzBybTY",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ### \u89e3\u51b3\u65b9\u6848\n",
        "\n",
        "\u70b9\u51fb\u4e0b\u65b9\u5373\u53ef\u67e5\u770b\u89e3\u51b3\u65b9\u6848\u3002"
      ]
    },
    {
      "metadata": {
        "id": "R5xOdYeQydi5",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "########################## SOLUTION CODE ########################################\n",
        "terms_embedding_column = tf.feature_column.embedding_column(terms_feature_column, dimension=2)\n",
        "feature_columns = [ terms_embedding_column ]\n",
        "\n",
        "my_optimizer = tf.train.AdagradOptimizer(learning_rate=0.1)\n",
        "my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
        "\n",
        "classifier = tf.estimator.DNNClassifier(\n",
        "  feature_columns=feature_columns,\n",
        "  hidden_units=[20,20],\n",
        "  optimizer=my_optimizer\n",
        ")\n",
        "#################################################################################\n",
        "\n",
        "classifier.train(\n",
        "  input_fn=lambda: _input_fn([train_path]),\n",
        "  steps=1000)\n",
        "\n",
        "evaluation_metrics = classifier.evaluate(\n",
        "  input_fn=lambda: _input_fn([train_path]),\n",
        "  steps=1000)\n",
        "print(\"Training set metrics:\")\n",
        "for m in evaluation_metrics:\n",
        "  print(m, evaluation_metrics[m])\n",
        "print(\"---\")\n",
        "\n",
        "evaluation_metrics = classifier.evaluate(\n",
        "  input_fn=lambda: _input_fn([test_path]),\n",
        "  steps=1000)\n",
        "\n",
        "print(\"Test set metrics:\")\n",
        "for m in evaluation_metrics:\n",
        "  print(m, evaluation_metrics[m])\n",
        "print(\"---\")"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "aiHnnVtzLS8w",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u4efb\u52a1 4\uff1a\u786e\u4fe1\u6a21\u578b\u4e2d\u786e\u5b9e\u5b58\u5728\u5d4c\u5165\n",
        "\n",
        "\u4e0a\u8ff0\u6a21\u578b\u4f7f\u7528\u4e86 `embedding_column`\uff0c\u800c\u4e14\u4f3c\u4e4e\u5f88\u6709\u6548\uff0c\u4f46\u8fd9\u5e76\u6ca1\u6709\u8ba9\u6211\u4eec\u4e86\u89e3\u5230\u5185\u90e8\u53d1\u751f\u7684\u60c5\u5f62\u3002\u6211\u4eec\u5982\u4f55\u68c0\u67e5\u8be5\u6a21\u578b\u786e\u5b9e\u5728\u5185\u90e8\u4f7f\u7528\u4e86\u5d4c\u5165\uff1f\n",
        "\n",
        "\u9996\u5148\uff0c\u6211\u4eec\u6765\u770b\u770b\u8be5\u6a21\u578b\u4e2d\u7684\u5f20\u91cf\uff1a"
      ]
    },
    {
      "metadata": {
        "id": "h1jNgLdQLS8w",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "classifier.get_variable_names()"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "Sl4-VctMLS8z",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u597d\u7684\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u8fd9\u91cc\u6709\u4e00\u4e2a\u5d4c\u5165\u5c42\uff1a`'dnn/input_from_feature_columns/input_layer/terms_embedding/...'`\u3002\uff08\u987a\u4fbf\u8bf4\u4e00\u4e0b\uff0c\u6709\u8da3\u7684\u662f\uff0c\u8be5\u5c42\u53ef\u4ee5\u4e0e\u6a21\u578b\u7684\u5176\u4ed6\u5c42\u4e00\u8d77\u8bad\u7ec3\uff0c\u5c31\u50cf\u6240\u6709\u9690\u85cf\u5c42\u4e00\u6837\u3002\uff09\n",
        "\n",
        "\u5d4c\u5165\u5c42\u7684\u5f62\u72b6\u662f\u5426\u6b63\u786e\uff1f\u8bf7\u8fd0\u884c\u4ee5\u4e0b\u4ee3\u7801\u6765\u67e5\u660e\u3002"
      ]
    },
    {
      "metadata": {
        "id": "JNFxyQUiLS80",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " **\u6ce8\u610f**\uff1a*\u5728\u6211\u4eec\u7684\u793a\u4f8b\u4e2d\uff0c\u5d4c\u5165\u662f\u4e00\u4e2a\u77e9\u9635\uff0c\u53ef\u8ba9\u6211\u4eec\u5c06\u4e00\u4e2a 50 \u7ef4\u77e2\u91cf\u6295\u5c04\u5230 2 \u7ef4\u7a7a\u95f4\u3002*"
      ]
    },
    {
      "metadata": {
        "id": "1xMbpcEjLS80",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "classifier.get_variable_value('dnn/input_from_feature_columns/input_layer/terms_embedding/embedding_weights').shape"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "MnLCIogjLS82",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u82b1\u4e9b\u65f6\u95f4\u6765\u624b\u52a8\u68c0\u67e5\u5404\u4e2a\u5c42\u53ca\u5176\u5f62\u72b6\uff0c\u4ee5\u786e\u4fdd\u4e00\u5207\u90fd\u6309\u7167\u60a8\u9884\u671f\u7684\u65b9\u5f0f\u4e92\u76f8\u8fde\u63a5\u3002"
      ]
    },
    {
      "metadata": {
        "id": "rkKAaRWDLS83",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u4efb\u52a1 5\uff1a\u68c0\u67e5\u5d4c\u5165\n",
        "\n",
        "\u73b0\u5728\uff0c\u6211\u4eec\u6765\u770b\u770b\u5b9e\u9645\u5d4c\u5165\u7a7a\u95f4\uff0c\u5e76\u4e86\u89e3\u672f\u8bed\u6700\u7ec8\u6240\u5728\u7684\u4f4d\u7f6e\u3002\u8bf7\u6267\u884c\u4ee5\u4e0b\u64cd\u4f5c\uff1a\n",
        "1. \u8fd0\u884c\u4ee5\u4e0b\u4ee3\u7801\u6765\u67e5\u770b\u6211\u4eec\u5728**\u4efb\u52a1 3** \u4e2d\u8bad\u7ec3\u7684\u5d4c\u5165\u3002\u4e00\u5207\u6700\u7ec8\u662f\u5426\u5982\u60a8\u6240\u9884\u671f\u7684\u90a3\u6837\uff1f\n",
        "\n",
        "2. \u91cd\u65b0\u8fd0\u884c**\u4efb\u52a1 3** \u4e2d\u7684\u4ee3\u7801\u6765\u91cd\u65b0\u8bad\u7ec3\u8be5\u6a21\u578b\uff0c\u7136\u540e\u518d\u6b21\u8fd0\u884c\u4e0b\u9762\u7684\u5d4c\u5165\u53ef\u89c6\u5316\u3002\u54ea\u4e9b\u4fdd\u6301\u4e0d\u53d8\uff1f\u54ea\u4e9b\u53d1\u751f\u4e86\u53d8\u5316\uff1f\n",
        "\n",
        "3. \u6700\u540e\uff0c\u4ec5\u4f7f\u7528 10 \u6b65\u6765\u91cd\u65b0\u8bad\u7ec3\u8be5\u6a21\u578b\uff08\u8fd9\u5c06\u4ea7\u751f\u4e00\u4e2a\u7cdf\u7cd5\u7684\u6a21\u578b\uff09\u3002\u518d\u6b21\u8fd0\u884c\u4e0b\u9762\u7684\u5d4c\u5165\u53ef\u89c6\u5316\u3002\u60a8\u73b0\u5728\u770b\u5230\u4e86\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\uff1f"
      ]
    },
    {
      "metadata": {
        "id": "s4NNu7KqLS84",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "embedding_matrix = classifier.get_variable_value('dnn/input_from_feature_columns/input_layer/terms_embedding/embedding_weights')\n",
        "\n",
        "for term_index in range(len(informative_terms)):\n",
        "  # Create a one-hot encoding for our term.  It has 0s everywhere, except for\n",
        "  # a single 1 in the coordinate that corresponds to that term.\n",
        "  term_vector = np.zeros(len(informative_terms))\n",
        "  term_vector[term_index] = 1\n",
        "  # We'll now project that one-hot vector into the embedding space.\n",
        "  embedding_xy = np.matmul(term_vector, embedding_matrix)\n",
        "  plt.text(embedding_xy[0],\n",
        "           embedding_xy[1],\n",
        "           informative_terms[term_index])\n",
        "\n",
        "# Do a little setup to make sure the plot displays nicely.\n",
        "plt.rcParams[\"figure.figsize\"] = (15, 15)\n",
        "plt.xlim(1.2 * embedding_matrix.min(), 1.2 * embedding_matrix.max())\n",
        "plt.ylim(1.2 * embedding_matrix.min(), 1.2 * embedding_matrix.max())\n",
        "plt.show() "
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "pUb3L7pqLS86",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u4efb\u52a1 6\uff1a\u5c1d\u8bd5\u6539\u8fdb\u6a21\u578b\u7684\u6548\u679c\n",
        "\n",
        "\u770b\u770b\u60a8\u80fd\u5426\u4f18\u5316\u8be5\u6a21\u578b\u4ee5\u6539\u8fdb\u5176\u6548\u679c\u3002\u60a8\u53ef\u4ee5\u5c1d\u8bd5\u4ee5\u4e0b\u51e0\u79cd\u505a\u6cd5\uff1a\n",
        "\n",
        "* **\u66f4\u6539\u8d85\u53c2\u6570**\u6216**\u4f7f\u7528\u5176\u4ed6\u4f18\u5316\u5de5\u5177**\uff0c\u6bd4\u5982 Adam\uff08\u901a\u8fc7\u9075\u5faa\u8fd9\u4e9b\u7b56\u7565\uff0c\u60a8\u7684\u51c6\u786e\u7387\u53ef\u80fd\u53ea\u4f1a\u63d0\u9ad8\u4e00\u4e24\u4e2a\u767e\u5206\u70b9\uff09\u3002\n",
        "* **\u5411 `informative_terms` \u4e2d\u6dfb\u52a0\u5176\u4ed6\u672f\u8bed\u3002**\u6b64\u6570\u636e\u96c6\u6709\u4e00\u4e2a\u5b8c\u6574\u7684\u8bcd\u6c47\u8868\u6587\u4ef6\uff0c\u5176\u4e2d\u5305\u542b 30716 \u4e2a\u672f\u8bed\uff0c\u60a8\u53ef\u4ee5\u5728\u4ee5\u4e0b\u4f4d\u7f6e\u627e\u5230\u8be5\u6587\u4ef6\uff1ahttps://download.mlcc.google.cn/mledu-datasets/sparse-data-embedding/terms.txt \u60a8\u53ef\u4ee5\u4ece\u8be5\u8bcd\u6c47\u8868\u6587\u4ef6\u4e2d\u6311\u9009\u51fa\u5176\u4ed6\u672f\u8bed\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 `categorical_column_with_vocabulary_file` \u7279\u5f81\u5217\u4f7f\u7528\u6574\u4e2a\u8bcd\u6c47\u8868\u6587\u4ef6\u3002"
      ]
    },
    {
      "metadata": {
        "id": "6-b3BqXvLS86",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "# Download the vocabulary file.\n",
        "terms_url = 'https://download.mlcc.google.cn/mledu-datasets/sparse-data-embedding/terms.txt'\n",
        "terms_path = tf.keras.utils.get_file(terms_url.split('/')[-1], terms_url)"      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "0jbJlwW5LS8-",
        "colab_type": "code",
        "colab": {
          "autoexec": {
            "startup": false,
            "wait_interval": 0
          }
        }
      },
      "source": [
        "# Create a feature column from \"terms\", using a full vocabulary file.\n",
        "informative_terms = None\n",
        "with io.open(terms_path, 'r', encoding='utf8') as f:\n",
        "  # Convert it to a set first to remove duplicates.\n",
        "  informative_terms = list(set(f.read().split()))\n",
        "  \n",
        "terms_feature_column = tf.feature_column.categorical_column_with_vocabulary_list(key=\"terms\", \n",
        "                                                                                 vocabulary_list=informative_terms)\n",
        "\n",
        "terms_embedding_column = tf.feature_column.embedding_column(terms_feature_column, dimension=2)\n",
        "feature_columns = [ terms_embedding_column ]\n",
        "\n",
        "my_optimizer = tf.train.AdagradOptimizer(learning_rate=0.1)\n",
        "my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
        "\n",
        "classifier = tf.estimator.DNNClassifier(\n",
        "  feature_columns=feature_columns,\n",
        "  hidden_units=[10,10],\n",
        "  optimizer=my_optimizer\n",
        ")\n",
        "\n",
        "classifier.train(\n",
        "  input_fn=lambda: _input_fn([train_path]),\n",
        "  steps=1000)\n",
        "\n",
        "evaluation_metrics = classifier.evaluate(\n",
        "  input_fn=lambda: _input_fn([train_path]),\n",
        "  steps=1000)\n",
        "print(\"Training set metrics:\")\n",
        "for m in evaluation_metrics:\n",
        "  print(m, evaluation_metrics[m])\n",
        "print(\"---\")\n",
        "\n",
        "evaluation_metrics = classifier.evaluate(\n",
        "  input_fn=lambda: _input_fn([test_path]),\n",
        "  steps=1000)\n",
        "\n",
        "print(\"Test set metrics:\")\n",
        "for m in evaluation_metrics:\n",
        "  print(m, evaluation_metrics[m])\n",
        "print(\"---\")"
      ],
      "cell_type": "code",
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "ew3kwGM-LS9B",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ## \u603b\u7ed3\n",
        "\n",
        "\u6211\u4eec\u53ef\u80fd\u83b7\u5f97\u4e86\u6bd4\u6211\u4eec\u539f\u6765\u7684\u7ebf\u6027\u6a21\u578b\u66f4\u597d\u4e14\u5177\u6709\u5d4c\u5165\u7684 DNN \u89e3\u51b3\u65b9\u6848\uff0c\u4f46\u7ebf\u6027\u6a21\u578b\u4e5f\u76f8\u5f53\u4e0d\u9519\uff0c\u800c\u4e14\u8bad\u7ec3\u901f\u5ea6\u5feb\u5f97\u591a\u3002\u7ebf\u6027\u6a21\u578b\u7684\u8bad\u7ec3\u901f\u5ea6\u4e4b\u6240\u4ee5\u66f4\u5feb\uff0c\u662f\u56e0\u4e3a\u5b83\u4eec\u6ca1\u6709\u592a\u591a\u8981\u66f4\u65b0\u7684\u53c2\u6570\u6216\u8981\u53cd\u5411\u4f20\u64ad\u7684\u5c42\u3002\n",
        "\n",
        "\u5728\u6709\u4e9b\u5e94\u7528\u4e2d\uff0c\u7ebf\u6027\u6a21\u578b\u7684\u901f\u5ea6\u53ef\u80fd\u975e\u5e38\u5173\u952e\uff0c\u6216\u8005\u4ece\u8d28\u91cf\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u7ebf\u6027\u6a21\u578b\u53ef\u80fd\u5b8c\u5168\u591f\u7528\u3002\u5728\u5176\u4ed6\u9886\u57df\uff0cDNN \u63d0\u4f9b\u7684\u989d\u5916\u6a21\u578b\u590d\u6742\u6027\u548c\u80fd\u529b\u53ef\u80fd\u66f4\u91cd\u8981\u3002\u5728\u5b9a\u4e49\u6a21\u578b\u67b6\u6784\u65f6\uff0c\u8bf7\u8bb0\u5f97\u8981\u5145\u5206\u63a2\u8ba8\u60a8\u7684\u95ee\u9898\uff0c\u4ee5\u4fbf\u77e5\u9053\u81ea\u5df1\u6240\u5904\u7684\u60c5\u5f62\u3002"
      ]
    },
    {
      "metadata": {
        "id": "9MquXy9zLS9B",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " ### *\u53ef\u9009\u5185\u5bb9\uff1a*\u5728 `embedding_column` \u4e0e `indicator_column` \u4e4b\u95f4\u8fdb\u884c\u6743\u8861\n",
        "\n",
        "\u4ece\u6982\u5ff5\u4e0a\u8bb2\uff0c\u5728\u8bad\u7ec3 `LinearClassifier` \u6216 `DNNClassifier` \u65f6\uff0c\u9700\u8981\u6839\u636e\u5b9e\u9645\u60c5\u51b5\u4f7f\u7528\u7a00\u758f\u5217\u3002TF \u63d0\u4f9b\u4e86\u4e24\u4e2a\u9009\u9879\uff1a`embedding_column` \u6216 `indicator_column`\u3002\n",
        "\n",
        "\u5728\u8bad\u7ec3 LinearClassifier\uff08\u5982**\u4efb\u52a1 1** \u4e2d\u6240\u793a\uff09\u65f6\uff0c\u7cfb\u7edf\u5728\u540e\u53f0\u4f7f\u7528\u4e86 `embedding_column`\u3002\u6b63\u5982**\u4efb\u52a1 2** \u4e2d\u6240\u793a\uff0c\u5728\u8bad\u7ec3 `DNNClassifier` \u65f6\uff0c\u60a8\u5fc5\u987b\u660e\u786e\u9009\u62e9 `embedding_column` \u6216 `indicator_column`\u3002\u672c\u90e8\u5206\u901a\u8fc7\u4e00\u4e2a\u7b80\u5355\u7684\u793a\u4f8b\u8ba8\u8bba\u4e86\u8fd9\u4e24\u8005\u4e4b\u95f4\u7684\u533a\u522b\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u4e8c\u8005\u4e4b\u95f4\u8fdb\u884c\u6743\u8861\u3002"
      ]
    },
    {
      "metadata": {
        "id": "M_3XuZ_LLS9C",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u5047\u8bbe\u6211\u4eec\u7684\u7a00\u758f\u6570\u636e\u5305\u542b `\"great\"`\u3001`\"beautiful\"` \u548c `\"excellent\"` \u8fd9\u51e0\u4e2a\u503c\u3002\u7531\u4e8e\u6211\u4eec\u5728\u6b64\u5904\u4f7f\u7528\u7684\u8bcd\u6c47\u8868\u5927\u5c0f\u4e3a $V = 50$\uff0c\u56e0\u6b64\u7b2c\u4e00\u5c42\u4e2d\u7684\u6bcf\u4e2a\u5355\u5143\uff08\u795e\u7ecf\u5143\uff09\u7684\u6743\u91cd\u5c06\u4e3a 50\u3002\u6211\u4eec\u7528 $s$ \u8868\u793a\u7a00\u758f\u8f93\u5165\u4e2d\u7684\u9879\u6570\u3002\u5bf9\u4e8e\u6b64\u793a\u4f8b\u7a00\u758f\u6570\u636e\uff0c$s = 3$\u3002\u5bf9\u4e8e\u5177\u6709 $V$ \u4e2a\u53ef\u80fd\u503c\u7684\u8f93\u5165\u5c42\uff0c\u5e26\u6709 $d$ \u4e2a\u5355\u5143\u7684\u9690\u85cf\u5c42\u9700\u8981\u8fd0\u884c\u4e00\u6b21\u201c\u77e2\u91cf - \u77e9\u9635\u201d\u4e58\u6cd5\u8fd0\u7b97\uff1a$(1 \\times V) * (V \\times d)$\u3002\u6b64\u8fd0\u7b97\u4f1a\u4ea7\u751f $O(V * d)$ \u7684\u8ba1\u7b97\u6210\u672c\u3002\u8bf7\u6ce8\u610f\uff0c\u6b64\u6210\u672c\u4e0e\u9690\u85cf\u5c42\u4e2d\u7684\u6743\u91cd\u6570\u6210\u6b63\u6bd4\uff0c\u800c\u4e0e $s$ \u65e0\u5173\u3002\n",
        "\n",
        "\u5982\u679c\u8f93\u5165\u4f7f\u7528 [`indicator_column`](https://www.tensorflow.org/api_docs/python/tf/feature_column/indicator_column) \u8fdb\u884c\u4e86\u72ec\u70ed\u7f16\u7801\uff08\u957f\u5ea6\u4e3a $V$ \u7684\u5e03\u5c14\u578b\u77e2\u91cf\uff0c\u5b58\u5728\u7528 1 \u8868\u793a\uff0c\u5176\u4f59\u5219\u4e3a 0\uff09\uff0c\u8fd9\u8868\u793a\u5f88\u591a\u96f6\u8fdb\u884c\u4e86\u76f8\u4e58\u548c\u76f8\u52a0\u8fd0\u7b97\u3002"
      ]
    },
    {
      "metadata": {
        "id": "I7mR4Wa2LS9C",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u5f53\u6211\u4eec\u901a\u8fc7\u4f7f\u7528\u5927\u5c0f\u4e3a $d$ \u7684 [`embedding_column`](https://www.tensorflow.org/api_docs/python/tf/feature_column/embedding_column) \u83b7\u5f97\u5b8c\u5168\u76f8\u540c\u7684\u7ed3\u679c\u65f6\uff0c\u6211\u4eec\u5c06\u4ec5\u67e5\u8be2\u4e0e\u793a\u4f8b\u8f93\u5165\u4e2d\u5b58\u5728\u7684 3 \u4e2a\u7279\u5f81 `\"great\"`\u3001`\"beautiful\"` \u548c `\"excellent\"` \u76f8\u5bf9\u5e94\u7684\u5d4c\u5165\u5e76\u5c06\u8fd9\u4e09\u4e2a\u5d4c\u5165\u76f8\u52a0\uff1a$(1 \\times d) + (1 \\times d) + (1 \\times d)$\u3002\u7531\u4e8e\u4e0d\u5b58\u5728\u7684\u7279\u5f81\u7684\u6743\u91cd\u5728\u201c\u77e2\u91cf-\u77e9\u9635\u201d\u4e58\u6cd5\u4e2d\u4e0e 0 \u76f8\u4e58\uff0c\u56e0\u6b64\u5bf9\u7ed3\u679c\u6ca1\u6709\u4efb\u4f55\u5f71\u54cd\uff1b\u800c\u5b58\u5728\u7684\u7279\u5f81\u7684\u6743\u91cd\u5728\u201c\u77e2\u91cf-\u77e9\u9635\u201d\u4e58\u6cd5\u4e2d\u4e0e 1 \u76f8\u4e58\u3002\u56e0\u6b64\uff0c\u5c06\u901a\u8fc7\u5d4c\u5165\u67e5\u8be2\u83b7\u5f97\u7684\u6743\u91cd\u76f8\u52a0\u4f1a\u83b7\u5f97\u4e0e\u201c\u77e2\u91cf-\u77e9\u9635\u201d\u4e58\u6cd5\u76f8\u540c\u7684\u7ed3\u679c\u3002\n",
        "\n",
        "\u5f53\u4f7f\u7528\u5d4c\u5165\u65f6\uff0c\u8ba1\u7b97\u5d4c\u5165\u67e5\u8be2\u662f\u4e00\u4e2a $O(s * d)$ \u8ba1\u7b97\uff1b\u4ece\u8ba1\u7b97\u65b9\u9762\u800c\u8a00\uff0c\u5b83\u6bd4\u7a00\u758f\u6570\u636e\u4e2d\u7684 `indicator_column` \u7684 $O(V * d)$ \u66f4\u5177\u6210\u672c\u6548\u76ca\uff0c\u56e0\u4e3a $s$ \u8fdc\u8fdc\u5c0f\u4e8e $V$\u3002\uff08\u8bf7\u6ce8\u610f\uff0c\u8fd9\u4e9b\u5d4c\u5165\u662f\u4e34\u65f6\u5b66\u4e60\u7684\u7ed3\u679c\u3002\u5728\u4efb\u4f55\u6307\u5b9a\u7684\u8bad\u7ec3\u8fed\u4ee3\u4e2d\uff0c\u90fd\u662f\u5f53\u524d\u67e5\u8be2\u7684\u6743\u91cd\u3002"
      ]
    },
    {
      "metadata": {
        "id": "etZ9qf0kLS9D",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        " \u6b63\u5982\u6211\u4eec\u5728**\u4efb\u52a1 3** \u4e2d\u770b\u5230\u7684\uff0c\u901a\u8fc7\u5728\u8bad\u7ec3 `DNNClassifier` \u8fc7\u7a0b\u4e2d\u4f7f\u7528 `embedding_column`\uff0c\u6211\u4eec\u7684\u6a21\u578b\u5b66\u4e60\u4e86\u7279\u5f81\u7684\u4f4e\u7ef4\u5ea6\u8868\u793a\u6cd5\uff0c\u5176\u4e2d\u70b9\u79ef\u5b9a\u4e49\u4e86\u4e00\u4e2a\u9488\u5bf9\u76ee\u6807\u4efb\u52a1\u7684\u76f8\u4f3c\u6027\u6307\u6807\u3002\u5728\u672c\u4f8b\u4e2d\uff0c\u5f71\u8bc4\u4e2d\u4f7f\u7528\u7684\u76f8\u4f3c\u672f\u8bed\uff08\u4f8b\u5982 `\"great\"` \u548c `\"excellent\"`\uff09\u5728\u5d4c\u5165\u7a7a\u95f4\u4e2d\u5f7c\u6b64\u4e4b\u95f4\u8ddd\u79bb\u8f83\u8fd1\uff08\u5373\u5177\u6709\u8f83\u5927\u7684\u70b9\u79ef\uff09\uff0c\u800c\u76f8\u5f02\u7684\u672f\u8bed\uff08\u4f8b\u5982 `\"great\"` \u548c `\"bad\"`\uff09\u5728\u5d4c\u5165\u7a7a\u95f4\u4e2d\u5f7c\u6b64\u4e4b\u95f4\u8ddd\u79bb\u8f83\u8fdc\uff08\u5373\u5177\u6709\u8f83\u5c0f\u7684\u70b9\u79ef\uff09\u3002"
      ]
    }
  ]
}
